/**
 * ZHU framework. Copyright 2012-, all rights reserved.
 *
 * $Id: WebRequestContextFilter.java 33 2012-08-30 08:10:18Z zhuxiaopeng $
 * $Revision: 33 $
 * $Date: 2012-08-30 16:10:18 +0800 (四, 2012-08-30) $
 * $Author: zhuxiaopeng $
 */
package zhu.framework.web.servlet;

import java.io.*;
import java.util.logging.*;

import javax.inject.*;
import javax.servlet.*;
import javax.servlet.Filter;
import javax.servlet.annotation.*;
import javax.servlet.http.*;

import zhu.framework.service.*;
import zhu.framework.web.*;

/**
 * <p>
 * </p>
 * 
 * @author $Author: zhuxiaopeng $
 * @version $Revision: 33 $ - $Date: 2012-08-30 16:10:18 +0800 (四, 2012-08-30) $
 */
@WebFilter(filterName = "WebRequestContextFilter", urlPatterns = "/faces/admin/*")
public final class WebRequestContextFilter implements Filter {

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
		if (WebContext.getInstance() instanceof HttpWebContext == false) {
			final IllegalStateException e = new IllegalStateException(String.format(
					"Unexpected EducomWebContext : HttpEducomWebContext is expected, but was actually %s", WebContext.getInstance()));
			logger.throwing("educom.framework.web.servlet.WebRequestContextFilter", "doFilter", e);
			throw e;
		}
		// WebRequestContextを構成する
		final WebContextBase globalContext = (WebContextBase) WebContext.getInstance();
		final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		final HttpSession session = getHttpSession(httpServletRequest);
		if (session != null) {
			final WebSessionContext sessionContext = getSessionContext(session);
			final ServiceRequestContext serviceContext = getServiceRequestContext(sessionContext);
			final WebRequestContext requestContext = new HttpWebRequestContext(serviceContext, httpServletRequest, sessionContext);

			if (sessionContext.getLoginStaff() == null) {
				((HttpServletResponse) response).sendRedirect(String.format("%s/faces/login.xhtml", request.getServletContext().getContextPath()));
			}
			globalContext.constructRequestContext(requestContext);
		}
		try {
			chain.doFilter(request, response);
		} finally {
			globalContext.destroyRequestContext();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(final FilterConfig filterConfig) throws ServletException {

	}

	private WebSessionContext getSessionContext(final HttpSession session) {
		final WebSessionContext sessionContext = getSessionContextIn(session);
		if (sessionContext == null) {
			final IllegalStateException e = new IllegalStateException("No WebSessionContext has been initialized.");
			logger.throwing("educom.framework.web.servlet.WebRequestContextFilter", "getSessionContext", e);
			throw e;
		}
		return sessionContext;
	}

	private HttpSession getHttpSession(final HttpServletRequest request) {
		return request.getSession(false);
	}

	private WebSessionContext getSessionContextIn(final HttpSession session) {
		final WebSessionContext sessionContext = (WebSessionContext) session.getAttribute(WebSessionContextListener.WEB_SESSION_CONTEXT_KEY);
		return sessionContext;
	}

	private ServiceRequestContext getServiceRequestContext(final WebSessionContext sessionContext) {
		return new DefaultServiceRequestContext(sessionContext.getLoginStaff());
	}

	@Inject
	private Logger logger;
}
